package com.example.basic.web.service.pharmIn.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.basic.base.impl.BaseEntityServiceImpl;
import com.example.basic.exception.ServiceException;
import com.example.basic.web.enums.DataCodeEnum;
import com.example.basic.web.enums.InParamStatusEnum;
import com.example.basic.web.mapper.pharmIn.PharmInRecordMapper;
import com.example.basic.web.model.binding.BindingInfo;
import com.example.basic.web.model.notice.InNotice;
import com.example.basic.web.model.pharmIn.PharmInRecord;
import com.example.basic.web.model.pharmStock.PharmStock;
import com.example.basic.web.response.InPharmResponse;
import com.example.basic.web.response.report.InOutRecordResponse;
import com.example.basic.web.service.binding.BindingInfoService;
import com.example.basic.web.service.common.CommonService;
import com.example.basic.web.service.dataCode.DataCodeService;
import com.example.basic.web.service.notice.InNoticeService;
import com.example.basic.web.service.pharmIn.PharmInRecordService;
import com.example.basic.web.service.pharmStock.PharmStockService;
import com.example.basic.web.service.zoneDepot.ZoneDepotService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import java.util.Map;

import static com.example.basic.utils.CheckUtil.notNull;


@Service
public class PharmInRecordServiceImpl extends BaseEntityServiceImpl<PharmInRecordMapper, PharmInRecord> implements PharmInRecordService {

    @Resource
    private PharmInRecordMapper pharmInRecordMapper;
    @Resource
    private DataCodeService dataCodeService;
    @Resource
    private PharmStockService pharmStockService;
    @Resource
    private InNoticeService inNoticeService;
    @Resource
    private CommonService commonService;
    @Resource
    private BindingInfoService bindingInfoService;
    @Resource
    private ZoneDepotService zoneDepotService;
    @Resource
    private HttpServletRequest request;


    /**
     * 新增入库单
     * @param pharmInRecord
     * @return
     */
    @Override
    public PharmInRecord add(PharmInRecord pharmInRecord) {
        notNull(pharmInRecord,"入库单实体不能为空");
        notNull(pharmInRecord.getInNoticeCode(),"通知单编码不能为空");

        //生成入库单编码
        String inPharmCode = dataCodeService.generateDataCodeNo(DataCodeEnum.IN_PHARM_CODE.getType());
        pharmInRecord.setInPharmCode(inPharmCode);

        preCreate(pharmInRecord);

        save(pharmInRecord);

        return this.mapper.selectById(pharmInRecord.getId());
    }

    /**
     * 通过通知单查询入库单
     * @param inNoticeCode
     * @return
     */
    @Override
    public PharmInRecord queryByNoticeCode(String inNoticeCode) {
        notNull(inNoticeCode,"通知单编码不能为空");

        LambdaQueryWrapper<PharmInRecord> lqw = new LambdaQueryWrapper<>();
        lqw.eq(PharmInRecord::getInNoticeCode,inNoticeCode);
        return this.mapper.selectOne(lqw);
    }

    @Override
    public Boolean remove(String inPharmCode) {
        notNull(inPharmCode,"入库单编码不能为空");

        LambdaQueryWrapper<PharmInRecord> lqw = new LambdaQueryWrapper<>();
        lqw.eq(PharmInRecord::getInPharmCode,inPharmCode);
        PharmInRecord pharmInRecord = this.mapper.selectOne(lqw);

        if(pharmInRecord == null){
            throw new ServiceException("未获取到需要删除的入库单");
        }

        if(this.deleteById(pharmInRecord.getId()) > 0){
            return true;
        }

        throw new ServiceException("删除失败");
    }

    /**
     * 入库单列表
     *
     * @param queryPage   分页
     * @param searchParam 遗体名称，拼音码，五笔码
     * @param sex         性别
     * @param pharmCode   库房编码
     * @param zoneCode    分区编码
     * @param depotCode   库位编码
     * @param status      状态
     * @param beginTime 开始日期
     * @param endTime 结束日期
     * @return
     */
    @Override
    public IPage<InPharmResponse> queryList(Page<InPharmResponse> queryPage, String searchParam, String sex, String pharmCode, String zoneCode, String depotCode, String status, String beginTime, String endTime) {
        return this.mapper.queryList(queryPage,searchParam,sex,pharmCode,zoneCode,depotCode,status,beginTime,endTime);
    }

    /**
     * 出入库记录查询
     * @param queryPage 分页
     * @param searchParam 模糊搜索(遗体名称，拼音码，五笔码)
     * @param pharmCode 库房编码 0-全部
     * @param zoneCode 分区编码 0-全部
     * @param depotCode 库位编码 0-全部
     * @param beginTime 开始时间
     * @param endTime 结束时间
     * @param type 出入库类型 0-全部
     * @return
     */
    @Override
    public IPage<InOutRecordResponse> queryInOutRecord(Page<InOutRecordResponse> queryPage, String searchParam, String pharmCode, String zoneCode, String depotCode, String beginTime, String endTime, String type) {
        return this.mapper.queryInOutRecord(queryPage,searchParam, pharmCode,zoneCode,depotCode,beginTime,endTime,type);
    }

    /**
     * 出入库记录统计
     *
     * @param searchParam 仓库编码
     * @param pharmCode   仓库编码
     * @param zoneCode    分区编码
     * @param depotCode 库位编码
     * @param beginTime 开始时间
     * @param endTime 结束时间
     * @param type 类型
     * @return
     */
    @Override
    public Map InOutRecordCount(String searchParam, String pharmCode, String zoneCode, String depotCode, String beginTime, String endTime, String type) {
        return this.mapper.InOutRecordCount(searchParam, pharmCode,zoneCode,depotCode,beginTime,endTime,type);
    }

    /**
     * 入库
     * @param inPharmCode 入库单编码
     */
    @Override
    public Boolean inPharm(String inPharmCode) {
        notNull(inPharmCode,"入库单编码不能为空");

        //获取入库单信息
        LambdaQueryWrapper<PharmInRecord> lqw = new LambdaQueryWrapper<>();
        lqw.eq(PharmInRecord::getInPharmCode,inPharmCode);
        PharmInRecord pharmInRecord = this.mapper.selectOne(lqw);
        if(pharmInRecord == null){
            throw new ServiceException("入库单编码无效");
        }

        //获取入库通知单
        InNotice inNotice = inNoticeService.detail(pharmInRecord.getInNoticeCode());

        //生成库存信息
        PharmStock pharmStock = new PharmStock();
        pharmStock.setRemainsCode(inNotice.getRemainsCode());
        pharmStock.setPharmCode(inNotice.getPharmCode());
        pharmStock.setZoneCode(inNotice.getZoneCode());
        pharmStock.setDepotCode(inNotice.getDepotCode());
        pharmStock.setInPharmCode(inPharmCode);
        pharmStock.setInDatetime(commonService.getDataBaseTime());
        pharmStock.setInOperPerson((String) request.getAttribute("userCode"));
        pharmStockService.add(pharmStock);

        //更新入库单状态
        pharmInRecord.setStatus(InParamStatusEnum.RECEIVE.getType());
        pharmInRecordMapper.updateById(pharmInRecord);

        //更新绑定关系 入库清空设备与担架板绑定关系
        BindingInfo bindingInfo = bindingInfoService.detail(inNotice.getRemainsCode());
        bindingInfo.setDeviceCode(null);
        bindingInfoService.modify(bindingInfo);

        return true;
    }

    /**
     * 入库单状态更新
     * @param inPharmCode 入库单编码
     * @return
     */
    @Override
    public Boolean modifyStatus(String inPharmCode) {
        notNull(inPharmCode,"入库单编码不能为空");

        //获取入库单信息
        LambdaQueryWrapper<PharmInRecord> lqw = new LambdaQueryWrapper<>();
        lqw.eq(PharmInRecord::getInPharmCode,inPharmCode);
        PharmInRecord pharmInRecord = this.mapper.selectOne(lqw);
        if(pharmInRecord == null){
            throw new ServiceException("入库单编码无效");
        }

        pharmInRecord.setStatus(InParamStatusEnum.IN_STORAGE.getType());
        preUpdate(pharmInRecord);
        pharmInRecordMapper.updateById(pharmInRecord);

        return true;
    }

    /**
     * 入库单详情
     * @param inPharmCode 入库单编码
     * @return
     */
    @Override
    public PharmInRecord detail(String inPharmCode) {
        notNull(inPharmCode, "入库单编码不能为空");

        //获取入库单信息
        LambdaQueryWrapper<PharmInRecord> lqw = new LambdaQueryWrapper<>();
        lqw.eq(PharmInRecord::getInPharmCode, inPharmCode);

        return this.mapper.selectOne(lqw);
    }

    /**
     * 更新入库单
     * @param pharmInRecord
     * @return
     */
    @Override
    public PharmInRecord update(PharmInRecord pharmInRecord) {
        preUpdate(pharmInRecord);

        this.updateById(pharmInRecord);

        return pharmInRecord;
    }
}
